
//****************************************************************************************
//*
//* File Name: ec_bsp_driver.c 
//* Level: driver
//* Version: v4.0
//* Date: 2024-07-09 13:05:10
//* Author: su
//* 
//****************************************************************************************/

//******************************** Includes *********************************//

#include "ec_bsp_aht21_reg.h"
#include "ec_bsp_aht21_driver.h"
#include "stdint.h"
//管理结构体内部的调用不需要函数传结构体
#define  iic aht21_instancetemp->piicdriver_interface 

//内部封装静态函数，结构体里函数指针的实体
static int8_t aht21_init                   (struct bsp_aht21 *aht21_instance);
static int8_t aht21_deinit                 (void);                      
static int8_t aht21_read_id                (void);                       
static int8_t aht21_read_temphumidata      (float *temp,float *humi);
static int8_t aht21_read_temperature       (float *temp);					      
static int8_t aht21_read_humidity          (float *humi);					     
static int8_t aht21_hibernating            (void);					      
static int8_t aht21_pfwakeup               (void);                      
static bsp_aht21_t * aht21_instancetemp;

//去初始化
int8_t aht21_deinit(void)
{
    //调用iic注销掉底层驱动
    return aht21_instancetemp->piicdriver_interface->pfdeinit();
}

//读取id，上电之后200毫秒之后进行读取，直接返回的数据为0X18，return返回成功
//如果没返回0X18，写入控制指令初始化相应寄存器
int8_t aht21_read_id(void)
{
	aht21_instancetemp->ptimebase_interface->delay_ms(200);
    uint8_t id = 0;
	
	aht21_instancetemp->piicdriver_interface->pfread_reg((AHT21_ADDR<<1) | 1,&id,1);
	if((id & 0x18) != 0x18)
    {
		uint8_t sendbuff[3] = {AHT21_reg_1,AHT21_reg_2,AHT21_reg_3};
		aht21_instancetemp->piicdriver_interface->pfwrite_reg((AHT21_ADDR<<1),sendbuff,1);
		aht21_instancetemp->ptimebase_interface->delay_ms(10);
		aht21_instancetemp->piicdriver_interface->pfread_reg((AHT21_ADDR<<1) | 1,&id,1);
		if((id & 0x18) != 0x18)
		{
			return -1;
		}
    }
	return 0;

}

//读取温湿度
int8_t aht21_read_temphumidata(float *temp,float *humi) {
    uint8_t sendbuff[3] = {AHT21_AC,AHT21_AC_1,AHT21_AC_2};
    uint8_t readdata[6] = {0};
    uint8_t state = 0;
    uint32_t data;
    // 发送测量温湿度的命令
    iic->pfwrite_reg((AHT21_ADDR<<1),sendbuff,(sizeof(sendbuff) / sizeof(uint8_t)));
    aht21_instancetemp->ptimebase_interface->delay_ms(80);
    iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
    state = readdata[0] >> 7;
    if(state)
    {
       aht21_instancetemp->ptimebase_interface->delay_ms(80); 
       iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
       state = readdata[0] >> 7;
       if(state)
       {
          return -1;
       }
    }	
	
    data = (uint32_t)((readdata[3] & 0x0f ) << 16) + (uint32_t)(readdata[4] << 8) +(uint32_t)readdata[5];
    *temp = data * (float)200.00 / (1 << 20) - 50; //计算得到温度值（放大了10倍）
     data = (uint32_t)(readdata[3] >> 4) + (uint32_t)(readdata[2] << 4) + (uint32_t)(readdata[1] << 12);
    *humi = data * (float)100.00 / (1 << 20);		
    if(( 0 == *temp) || (0 == *humi))
    {
        return -1;
    }

    return 0;
}

//读取温度测量函数需传入提前定义好的浮点数
int8_t aht21_read_temperature(float *temp) {
    uint8_t sendbuff[3] = {AHT21_AC,AHT21_AC_1,AHT21_AC_2};
    uint8_t readdata[6] = {0};
    uint8_t state = 0;
    uint32_t data;
    // 发送测量温度的命令
    iic->pfwrite_reg((AHT21_ADDR<<1),sendbuff,(sizeof(sendbuff) / sizeof(uint8_t)));
    aht21_instancetemp->ptimebase_interface->delay_ms(80);
    iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
    state = readdata[0] >> 7;
    if(state)
    {
       aht21_instancetemp->ptimebase_interface->delay_ms(80); 
       iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
       state = readdata[0] >> 7;
       if(state)
       {
          return -1;
       }
    }	
	
    data = (uint32_t)((readdata[3] & 0x0f ) << 16) + (uint32_t)(readdata[4] << 8) +(uint32_t)readdata[5];
    *temp = data * (float)200.00 / (1 << 20) - 50; //计算得到温度值（放大了10倍）		
    if(!*temp)
    {
        return -1;
    }
    return 0;
}

//读取湿度测量函数需传入提前定义好的浮点数
int8_t aht21_read_humidity(float *humi) {
    uint8_t sendbuff[3] = {AHT21_AC,AHT21_AC_1,AHT21_AC_2};
    uint8_t readdata[6] = {0};
    uint8_t state = 0;
    uint32_t data;
    // 发送测量湿度的命令
    iic->pfwrite_reg((AHT21_ADDR<<1),sendbuff,(sizeof(sendbuff) / sizeof(uint8_t)));
    aht21_instancetemp->ptimebase_interface->delay_ms(80);
    iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
    state = readdata[0] >> 7;
    if(state)
    {
       aht21_instancetemp->ptimebase_interface->delay_ms(80); 
       iic->pfread_reg((AHT21_ADDR<<1) | (1),readdata,(sizeof(readdata) / sizeof(uint8_t)));
       state = readdata[0] >> 7;
       if(state)
       {
          return -1;
       }
    }
    data = (uint32_t)(readdata[3] >> 4) + (uint32_t)(readdata[2] << 4) + (uint32_t)(readdata[1] << 12);
    *humi = data * (float)100.00 / (1 << 20);
    if(!*humi)
    {
        return -1;
    }
    return 0;
}


int8_t aht21_hibernating(void)
{
    
    return iic->pfwrite_reg((AHT21_ADDR<<0),AHT21_IDLE,1); 
}

int8_t aht21_pfwakeup(void)
{

    return iic->pfwrite_reg((AHT21_ADDR<<0),(uint8_t *)AHT21_BUSY,1);
}

int8_t aht21_inst(struct bsp_aht21 *aht21_instance,
				 iic_driver_interface_t *iic_instance,
				 system_timebase_interface_t *timebase)
{
   if (aht21_instance == NULL || iic_instance  == NULL )
   {                                          
       return -1;
   }
    //绑定aht21底层驱动
    aht21_instancetemp = aht21_instance;
    aht21_instance->piicdriver_interface = iic_instance;
    aht21_instance->ptimebase_interface  =  timebase;     	    
	//绑定函数
	aht21_instance->pfinit    			 = aht21_init;
    aht21_instance->pfdeinit  			 = aht21_deinit;

    aht21_instance->pfread_temphumidata  = aht21_read_temphumidata;
    aht21_instance->pfread_humidity 	 = aht21_read_humidity;
    aht21_instance->pfread_temperature   = aht21_read_temperature;
    aht21_instance->pfhibernating 		 = aht21_hibernating;
    aht21_instance->pfwakeup 			 = aht21_pfwakeup;
	if(0 != aht21_instance->pfinit(aht21_instance))
	{
		return -2;
	}
	    aht21_instance->pfread_id		    = aht21_read_id;
    if(0 != aht21_instance->pfread_id())
	{
		return -3;
	}
    return 0;
}

int8_t aht21_init(struct bsp_aht21 *aht21_instance)
{
	return aht21_instance->piicdriver_interface->pfinit();	
}
